<template>
  <div class="data-detail">
    <div class="header-bar">
      <el-button @click="router.back()" type="primary" size="small"
        >返回</el-button
      >
      <span class="title">任务详情查看</span>
      <div class="data-info" v-if="taskDetail.taskId">
        <el-tag size="small" type="info">任务ID: {{ taskDetail.taskId }}</el-tag>
        <el-tag size="small" type="success">{{ taskDetail.taskName }}</el-tag>
        <el-tag size="small" :type="taskDetail.status === '0' ? 'success' : 'danger'">
          {{ taskDetail.status === '0' ? '正常' : '停用' }}
        </el-tag>
        <el-tag size="small" type="warning">关联数据: {{ videoDataList.length }} 个</el-tag>
      </div>
    </div>
    <div class="detail-content-area" v-loading="loading">

            <!-- 视频模块：与DataCollection.vue一致 -->
      <div class="video-toolbar">
        <div class="toolbar-left">
          <el-button
            @click="enlargeSelectedVideos"
            :disabled="selectedVideos.length === 0"
            type="primary"
            size="small"
          >
            <el-icon><ZoomIn /></el-icon>
            放大选中视频 ({{ selectedVideos.length }})
          </el-button>
          <el-button @click="selectAllVideos" size="small">
            {{ selectedVideos.length === localFiles.videos.length ? "取消全选" : "全选" }}
          </el-button>
        </div>
        <div class="toolbar-right">
          <span class="toolbar-label">窗口布局</span>
          <el-select
            v-model="windowLayout"
            size="small"
            style="width: 120px"
            @change="refreshGrid"
          >
            <el-option label="每行2路" value="2" />
            <el-option label="每行3路" value="3" />
            <el-option label="每行4路" value="4" />
          </el-select>
        </div>
      </div>
      <div class="video-scroll-wrapper">
        <div v-if="localFiles.videos.length === 0" class="no-videos">
          <el-empty description="暂无视频文件" :image-size="80">
            <template #description>
              <div class="empty-content">
                <p class="empty-title">未找到视频文件</p>
                <p class="empty-tip">该任务关联的数据中没有找到视频文件</p>
              </div>
            </template>
          </el-empty>
        </div>
        <div v-else class="video-grid" :style="gridStyle">
          <div
            v-for="(video, index) in localFiles.videos"
            :key="index"
            class="video-card"
            :class="{ selected: selectedVideos.includes(index) }"
          >
            <div class="video-card-topbar">
              <el-tooltip :content="video.fileName" placement="top" :show-after="500">
                <span class="video-title">{{ video.fileName }}</span>
              </el-tooltip>
            </div>
            <div class="video-card-icons">
              <el-tooltip content="最大化" placement="top">
                <el-icon class="video-icon" @click.stop="maximizeVideo(index)">
                  <FullScreen />
                </el-icon>
              </el-tooltip>
            </div>
            <div class="video-card-body">
              <VideoPlayer
                :ref="(el) => (videoRefs[index] = el)"
                :video-src="`file://${video.localPath}`"
                :poster="getVideoPoster(index)"
                :disabled="videoStatus[index] !== 'online'"
                :hide-controls="true"
                :disable-click="true"
                :current-time="currentPlaybackTime"
                :is-playing="isPlaying"
                @timeupdate="onVideoTimeUpdate"
                @loadedmetadata="onVideoLoaded(index)"
                @ended="onVideoEnded"
              />
              <!-- 视频选择复选框 -->
              <div class="video-checkbox">
                <el-checkbox
                  v-model="selectedVideos"
                  :value="index"
                  @change="onVideoSelect"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 遥测数据图表 -->
      <div class="chart-section">
        <div class="section-header">
          <h3>遥测数据</h3>
          <div class="chart-info">
            <span>历史数据回放</span>
            <span style="margin-left: 20px"
              >数据点：{{ historicalData.length }} 个</span
            >
          </div>
        </div>
        <div class="chart-area">
          <div v-if="historicalData.length === 0" class="no-telemetry">
            <el-empty description="暂无遥测数据" :image-size="60">
              <template #description>
                <div class="empty-content">
                  <p class="empty-title">未找到遥测数据文件</p>
                  <p class="empty-tip">请检查 telemetry_data.json 文件是否存在</p>
                </div>
              </template>
            </el-empty>
          </div>
          <HistoricalChart
            v-else
            :historical-data="historicalData"
            ref="historicalChartRef"
            @time-change="onChartTimeChange"
            @playback-complete="onTelemetryPlaybackComplete"
          />
        </div>
      </div>
      <!-- 播放控制区域 -->
      <div class="playback-section" v-if="localFiles.videos.length > 0">
        <div class="playback-controls">
          <div class="control-left">
            <span class="current-time">{{
              formatPlaybackTime(currentPlaybackTime)
            }}</span>
            <el-button
              :icon="isPlaying ? VideoPause : VideoPlay"
              @click="togglePlayback"
              size="small"
              circle
              class="play-btn"
            />
            <el-button @click="seekBackward" size="small" circle>
              <el-icon><DArrowLeft /></el-icon>
            </el-button>
            <el-button @click="seekForward" size="small" circle>
              <el-icon><DArrowRight /></el-icon>
            </el-button>
          </div>
          <div class="progress-container">
            <el-slider
              v-model="playbackProgress"
              :max="100"
              @change="onProgressChange"
              @input="onProgressInput"
              :show-tooltip="false"
              class="progress-slider"
            />
          </div>
          <div class="control-right">
            <span class="total-time">{{
              formatPlaybackTime(totalPlaybackTime)
            }}</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 放大视频弹窗 -->
    <el-dialog
      v-model="showEnlargedDialog"
      title="多路视频放大显示"
      :fullscreen="true"
      :show-close="true"
      :close-on-click-modal="false"
      :close-on-press-escape="true"
      :before-close="closeEnlargedDialog"
      class="enlarged-video-dialog fullscreen-dialog"
    >
      <template #header>
        <div class="fullscreen-header">
          <span class="dialog-title">多路视频放大显示</span>
        </div>
      </template>

      <div class="enlarged-video-container">
        <div
          class="enlarged-video-grid"
          :style="enlargedGridStyle"
          :class="enlargedGridClass"
        >
          <div
            v-for="videoIndex in selectedVideos"
            :key="videoIndex"
            class="enlarged-video-item"
            :class="enlargedItemClass"
          >
            <div class="enlarged-video-header">
              <el-tooltip :content="getVideoTitle(videoIndex)" placement="top" :show-after="500">
                <span>{{ getVideoTitle(videoIndex) }}</span>
              </el-tooltip>
            </div>
            <VideoPlayer
              :ref="(el) => (enlargedVideoRefs[videoIndex] = el)"
              :video-src="getVideoSrcForIndex(videoIndex)"
              :poster="getVideoPoster(videoIndex)"
              :current-time="currentPlaybackTime"
              :is-playing="isPlaying"
              :playback-speed="playbackSpeed"
              :hide-controls="true"
              :disable-click="true"
              @timeupdate="onVideoTimeUpdate"
              @loadedmetadata="onVideoLoaded(videoIndex)"
              @ended="onVideoEnded"
            />
          </div>
        </div>

        <!-- 弹窗内的统一播放控制条 -->
        <div class="enlarged-playback-controls">
          <div class="enlarged-control-left">
            <span class="current-time">{{
              formatPlaybackTime(currentPlaybackTime)
            }}</span>
            <el-button
              :icon="isPlaying ? VideoPause : VideoPlay"
              @click="togglePlayback"
              size="small"
              circle
              class="play-btn"
            />
            <el-button @click="seekBackward" size="small" circle>
              <el-icon><DArrowLeft /></el-icon>
            </el-button>
            <el-button @click="seekForward" size="small" circle>
              <el-icon><DArrowRight /></el-icon>
            </el-button>
          </div>
          <div class="enlarged-progress-container">
            <el-slider
              v-model="playbackProgress"
              :max="100"
              @change="onProgressChange"
              @input="onProgressInput"
              :show-tooltip="false"
              class="progress-slider"
            />
          </div>
          <div class="enlarged-control-right">
            <span class="total-time">{{
              formatPlaybackTime(totalPlaybackTime)
            }}</span>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
  VideoPlay,
  VideoPause,
  FullScreen,
  ZoomIn,
  DArrowLeft,
  DArrowRight,
  Close,
  Refresh,
} from "@element-plus/icons-vue";
import HistoricalChart from "../components/charts/HistoricalChart.vue";
import VideoPlayer from "../components/VideoPlayer.vue";


const route = useRoute();
const router = useRouter();
const taskId = route.params.id;
const relatedDataIds = route.params.related ? route.params.related.split(',').map(id => parseInt(id)) : [];

// 任务详情数据
const taskDetail = ref({});
const videoDataList = ref([]); // 存储videoDataList数组
const localFiles = ref({
  videos: [],
  telemetry: null,
  metadata: null
});
const loading = ref(false);

// 加载任务详情
const loadTaskDetail = async () => {
  loading.value = true;
  try {
    console.log('加载任务详情，taskId:', taskId, 'relatedDataIds:', relatedDataIds);

    // 从sessionStorage获取任务详情（包含videoDataList）
    const storedTaskData = sessionStorage.getItem('taskDetail');
    if (storedTaskData) {
      const taskData = JSON.parse(storedTaskData);
      taskDetail.value = {
        taskId: taskData.taskId || taskId,
        taskName: taskData.taskName || `任务${taskId}`,
        startTime: taskData.startTime || '2025-07-31 09:00:00',
        endTime: taskData.endTime || '2025-07-31 10:00:00',
        status: taskData.status || '0',
        remark: taskData.remark || '测试任务'
      };
      videoDataList.value = taskData.videoDataList || [];
      console.log('从sessionStorage获取的任务详情:', taskDetail.value);
      console.log('videoDataList:', videoDataList.value);
    } else {
      // 如果没有存储的数据，使用默认数据
      taskDetail.value = {
        taskId: taskId,
        taskName: `任务${taskId}`,
        startTime: '2025-07-31 09:00:00',
        endTime: '2025-07-31 10:00:00',
        status: '0',
        remark: '测试任务'
      };
      videoDataList.value = [];
    }

    // 根据videoDataList获取本地文件
    if (videoDataList.value.length > 0) {
      await loadLocalFiles();
    }
  } catch (error) {
    console.error('加载任务详情失败:', error);
  } finally {
    loading.value = false;
  }
};

// 根据videoDataList加载本地文件
const loadLocalFiles = async () => {
  try {
    console.log('正在加载videoDataList中的本地文件，数据项数量:', videoDataList.value.length);

    // 合并所有视频文件和遥测文件
    const allVideos = [];
    const allTelemetry = [];

    for (const dataItem of videoDataList.value) {
      if (dataItem.storagePath) {
        console.log(`正在加载数据 ${dataItem.dataId} 的文件，storagePath:`, dataItem.storagePath);

        // 调用Electron API获取本地文件信息
        const result = await window.electronAPI.getCollectionFiles({
          storagePath: dataItem.storagePath
        });

        if (result.success) {
          console.log(`数据 ${dataItem.dataId} 的文件加载成功:`, result.files);

          // 添加视频文件
          if (result.files.videos && result.files.videos.length > 0) {
            allVideos.push(...result.files.videos);
          }

          // 添加遥测文件（如果有的话）
          if (result.files.telemetry) {
            allTelemetry.push(result.files.telemetry);
          }
        } else {
          console.error(`数据 ${dataItem.dataId} 的文件加载失败:`, result.error);
        }
      }
    }

    // 更新本地文件信息
    localFiles.value = {
      videos: allVideos,
      telemetry: allTelemetry.length > 0 ? allTelemetry[0] : null, // 暂时只使用第一个遥测文件
      metadata: null
    };

    console.log('合并后的本地文件信息:', localFiles.value);

    // 打印每个视频文件的完整路径
    if (localFiles.value.videos) {
      localFiles.value.videos.forEach((video, index) => {
        console.log(`视频 ${index + 1}:`, {
          fileName: video.fileName,
          localPath: video.localPath,
          fileUrl: `file://${video.localPath}`
        });
      });
    }

    // 加载遥测数据
    await loadTelemetryData();

    // 初始化视频状态
    initializeVideoStatus();
  } catch (error) {
    console.error('加载本地文件失败:', error);
  }
};

const windowLayout = ref(4);
const videoRefs = ref([]);
const enlargedVideoRefs = ref([]);
const videoStatus = ref([]);

// 根据视频数量初始化状态
const initializeVideoStatus = () => {
  const videoCount = localFiles.value.videos.length;
  videoStatus.value = Array(videoCount).fill("online");
};
const currentPlaybackTime = ref(0);
const totalPlaybackTime = ref(0); // 初始化为0，等待视频加载后更新
const playbackProgress = ref(0);
const isPlaying = ref(false);
const playbackSpeed = ref(1);
const historicalChartRef = ref();

// 新增：视频选择相关
const selectedVideos = ref([]);
const showEnlargedDialog = ref(false);

const historicalData = ref([]);

// 加载遥测数据
const loadTelemetryData = async () => {
  if (localFiles.value.telemetry) {
    try {
      const telemetryResult = await window.electronAPI.readTelemetryFile({
        filePath: localFiles.value.telemetry.localPath
      });
      if (telemetryResult && telemetryResult.success) {
        historicalData.value = telemetryResult.data.data || [];
        console.log('遥测数据加载成功:', historicalData.value.length, '个数据点');
      }
    } catch (error) {
      console.error('加载遥测数据失败:', error);
      historicalData.value = [];
    }
  }
};

const gridStyle = computed(() => {
  return {
    display: "grid",
    gridTemplateColumns: `repeat(${windowLayout.value}, 1fr)`,
    gap: "16px",
    minHeight: 0,
    padding: "0",
  };
});

const enlargedGridStyle = computed(() => {
  const count = selectedVideos.value.length;

  if (count === 1) {
    return {
      display: "flex",
      alignItems: "stretch",
      justifyContent: "stretch",
      width: "100%",
      height: "100%",
    };
  }

  let columns = 1;
  if (count <= 4) columns = 2;
  else if (count <= 9) columns = 3;
  else columns = 4;

  return {
    display: "grid",
    gridTemplateColumns: `repeat(${columns}, 1fr)`,
    gap: "16px",
  };
});

const enlargedGridClass = computed(() => {
  return selectedVideos.value.length === 1 ? "single-video" : "multi-video";
});

const enlargedItemClass = computed(() => {
  return selectedVideos.value.length === 1 ? "single-video" : "";
});

// 视频选择功能
const onVideoSelect = () => {
  // 复选框变化时的处理
};

const selectAllVideos = () => {
  const videoCount = localFiles.value.videos.length;
  if (selectedVideos.value.length === videoCount) {
    selectedVideos.value = [];
  } else {
    selectedVideos.value = Array.from({ length: videoCount }, (_, i) => i);
  }
};

const enlargeSelectedVideos = () => {
  if (selectedVideos.value.length === 0) return;
  showEnlargedDialog.value = true;
};

const closeEnlargedDialog = () => {
  showEnlargedDialog.value = false;
};

const fullscreenSingleVideo = (videoIndex) => {
  enlargedVideoRefs.value[videoIndex]?.toggleFullscreen?.();
};

// 播放控制功能
const togglePlayback = () => {
  console.log('togglePlayback called, current isPlaying:', isPlaying.value);
  isPlaying.value = !isPlaying.value;
  console.log('new isPlaying value:', isPlaying.value);

  // 如果当前时间已经到达末尾，重新开始播放
  if (isPlaying.value && currentPlaybackTime.value >= totalPlaybackTime.value - 0.1) {
    console.log('Resetting to start for replay');
    currentPlaybackTime.value = 0;
    playbackProgress.value = 0;
  }

  syncAllVideos();
  if (historicalChartRef.value) {
    historicalChartRef.value.toggleRealTime?.();
  }
};

const seekForward = () => {
  const newTime = Math.min(
    currentPlaybackTime.value + 10,
    totalPlaybackTime.value
  );
  seekToTime(newTime);
};

const seekBackward = () => {
  const newTime = Math.max(currentPlaybackTime.value - 10, 0);
  seekToTime(newTime);
};

const seekToTime = (time) => {
  currentPlaybackTime.value = time;
  playbackProgress.value = (time / totalPlaybackTime.value) * 100;
  syncAllVideos();
};

const onSpeedChange = () => {
  syncAllVideos();
};

// 拖动进度条时，所有视频都 setCurrentTime，短视频超出 duration 后保持最后一帧
const syncAllVideos = () => {
  videoRefs.value.forEach((video) => {
    if (video) {
      const duration = video.getDuration?.() || 0;
      const time = Math.min(currentPlaybackTime.value, duration);
      video.setCurrentTime?.(time);
      video.setPlaybackRate?.(playbackSpeed.value);
      if (isPlaying.value) {
        // 如果当前时间等于或超过视频时长，且正在播放，说明需要重新开始
        if (time >= duration) {
          video.setCurrentTime?.(0);
          video.play?.();
        } else {
          video.play?.();
        }
      } else {
        video.pause?.();
      }
    }
  });
  Object.values(enlargedVideoRefs.value).forEach((video) => {
    if (video) {
      const duration = video.getDuration?.() || 0;
      const time = Math.min(currentPlaybackTime.value, duration);
      video.setCurrentTime?.(time);
      video.setPlaybackRate?.(playbackSpeed.value);
      if (isPlaying.value) {
        // 如果当前时间等于或超过视频时长，且正在播放，说明需要重新开始
        if (time >= duration) {
          video.setCurrentTime?.(0);
          video.play?.();
        } else {
          video.play?.();
        }
      } else {
        video.pause?.();
      }
    }
  });
};

const onVideoTimeUpdate = (time) => {
  if (!isPlaying.value) return;

  // 获取所有视频中最大的当前时间，避免短视频结束后时间回退
  let maxCurrentTime = time;
  videoRefs.value.forEach(video => {
    if (video && video.getCurrentTime) {
      const videoTime = video.getCurrentTime();
      if (videoTime > maxCurrentTime) {
        maxCurrentTime = videoTime;
      }
    }
  });

  currentPlaybackTime.value = maxCurrentTime;
  // 只有在非拖动状态下才更新进度条，避免跳动
  if (!isDragging) {
    // 确保进度条在播放完成时显示100%
    const progress = (maxCurrentTime / totalPlaybackTime.value) * 100;
    playbackProgress.value = Math.min(100, Math.max(0, progress));

    // 如果接近播放完成（99.5%以上），强制设置为100%
    if (progress >= 99.5) {
      playbackProgress.value = 100;
    }
  }
};

let previewDebounceTimer = null;
let isDragging = false;

const onProgressInput = (value) => {
  isDragging = true;
  // 拖动时不更新 playbackProgress，避免与 onVideoTimeUpdate 冲突
  // 只更新视频时间进行预览
  const previewTime = (value / 100) * totalPlaybackTime.value;

  // 拖动时暂停所有视频，避免卡顿
  videoRefs.value.forEach(video => video?.pause?.());
  Object.values(enlargedVideoRefs.value).forEach(video => video?.pause?.());

  // 防抖预览帧：每 200ms 同步一次所有视频 currentTime 和遥测数据
  if (previewDebounceTimer) clearTimeout(previewDebounceTimer);
  previewDebounceTimer = setTimeout(() => {
    videoRefs.value.forEach(video => video?.setCurrentTime?.(previewTime));
    Object.values(enlargedVideoRefs.value).forEach(video => video?.setCurrentTime?.(previewTime));

    // 同步遥测数据到对应时间点
    if (historicalChartRef.value) {
      historicalChartRef.value.seekToTime?.(previewTime);
    }
  }, 200);
};

const onProgressChange = (value) => {
  isDragging = false;
  // 清除防抖定时器
  if (previewDebounceTimer) {
    clearTimeout(previewDebounceTimer);
    previewDebounceTimer = null;
  }

  const newTime = (value / 100) * totalPlaybackTime.value;
  seekToTime(newTime); // 这里会调用 syncAllVideos

  // 同步遥测数据到对应时间点
  if (historicalChartRef.value) {
    historicalChartRef.value.seekToTime?.(newTime);
  }

  // 松开后恢复播放（如果 isPlaying）
  if (isPlaying.value) {
    videoRefs.value.forEach(video => video?.play?.());
    Object.values(enlargedVideoRefs.value).forEach(video => video?.play?.());
  }
};

const onChartTimeChange = (time) => {
  seekToTime(time);
};

// 遥测数据播放完成时的处理
const onTelemetryPlaybackComplete = () => {
  // 检查是否所有视频都播放完成
  const allVideosEnded = videoRefs.value.every(video => {
    if (video && video.getDuration && video.getCurrentTime) {
      const duration = video.getDuration();
      const currentTime = video.getCurrentTime();
      return currentTime >= duration - 0.1; // 允许0.1秒的误差
    }
    return false;
  });

  if (allVideosEnded) {
    // 所有视频和遥测数据都播放完成，重置到初始状态
    isPlaying.value = false;
    currentPlaybackTime.value = 0;
    playbackProgress.value = 0;
    syncAllVideos();
    // 重置遥测数据到初始状态
    if (historicalChartRef.value) {
      historicalChartRef.value.resetPlayback?.();
    }
  }
};

// 视频播放完成时的处理
const onVideoEnded = () => {
  // 检查是否所有视频都播放完成
  const allVideosEnded = videoRefs.value.every(video => {
    if (video && video.getDuration && video.getCurrentTime) {
      const duration = video.getDuration();
      const currentTime = video.getCurrentTime();
      return currentTime >= duration - 0.1; // 允许0.1秒的误差
    }
    return false;
  });

  if (allVideosEnded && isPlaying.value) {
    // 所有视频都播放完成，重置到初始状态
    isPlaying.value = false;
    currentPlaybackTime.value = 0;
    playbackProgress.value = 0;
    syncAllVideos();
    // 同时暂停遥测数据播放并重置到初始状态
    if (historicalChartRef.value) {
      historicalChartRef.value.stopPlayback?.();
      historicalChartRef.value.resetPlayback?.();
    }
  }
};

// 保持原有功能
const refreshGrid = () => {};
const maximizeVideo = (i) => {
  videoRefs.value[i]?.toggleFullscreen?.();
};

// getVideoSrc 根据本地文件获取视频源
const getVideoSrc = (index) => {
  // index 从 1 开始，对应数组索引 index-1
  if (localFiles.value.videos && localFiles.value.videos.length > 0) {
    const videoIndex = index - 1;
    if (videoIndex < localFiles.value.videos.length) {
      return `file://${localFiles.value.videos[videoIndex].localPath}`;
    }
  }
  // 如果没有本地文件，返回默认测试视频
  return '/test.mp4';
};

const getVideoPoster = (index) => {
  return `/placeholder.svg?height=200&width=300&text=摄像头${index}`;
};

const formatPlaybackTime = (seconds) => {
  if (!seconds || isNaN(seconds)) return "00:00";
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins.toString().padStart(2, "0")}:${secs
    .toString()
    .padStart(2, "0")}`;
};

// 更新总播放时长 - 根据实际视频文件
const updateTotalPlaybackTime = () => {
  if (localFiles.value.videos && localFiles.value.videos.length > 0) {
    // 获取所有视频的最大时长
    const durations = localFiles.value.videos.map((video, index) => {
      const videoRef = videoRefs.value[index];
      return videoRef && videoRef.getDuration ? videoRef.getDuration() : 0;
    });

    const maxDuration = Math.max(...durations);
    if (maxDuration && maxDuration !== totalPlaybackTime.value) {
      totalPlaybackTime.value = maxDuration;
      console.log(`更新总播放时长: ${maxDuration}秒 (${formatPlaybackTime(maxDuration)})`);
    }
  }
};

// 视频加载完成事件
const onVideoLoaded = (index) => {
  console.log(`视频 ${index + 1} 加载完成`);
  // 延迟更新总时长，确保所有视频都已加载
  setTimeout(updateTotalPlaybackTime, 500);
};

// 获取视频标题
const getVideoTitle = (index) => {
  if (localFiles.value.videos && localFiles.value.videos[index]) {
    return localFiles.value.videos[index].fileName;
  }
  return `摄像头 ${index + 1}`;
};

// 获取指定索引的视频源
const getVideoSrcForIndex = (index) => {
  if (localFiles.value.videos && localFiles.value.videos[index]) {
    return `file://${localFiles.value.videos[index].localPath}`;
  }
  return '/test.mp4';
};



// 监听视频引用变化，更新总时长
watch(videoRefs, () => {
  // 延迟更新，确保视频已加载
  setTimeout(updateTotalPlaybackTime, 1000);
}, { deep: true });

// 弹窗打开时/refs变化时尝试刷新 duration
watch([showEnlargedDialog, enlargedVideoRefs, selectedVideos], ([show]) => {
  if (show) {
    nextTick(() => {
      setTimeout(updateTotalPlaybackTime, 500);
    });
  }
});

// 监听本地文件变化，自动初始化视频状态
watch(localFiles, async (newFiles) => {
  if (newFiles.videos && newFiles.videos.length > 0) {
    initializeVideoStatus();
  }
}, { deep: true });

// 页面初始化
const initPage = async () => {
  await loadTaskDetail();
};



</script>

<style scoped>
.data-detail {
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 16px;
  gap: 16px;
  overflow: hidden;
  background: #f5f5f5;
}
.header-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 0;
  flex-shrink: 0;
}
.title {
  font-size: 18px;
  font-weight: bold;
}

.data-info {
  display: flex;
  gap: 8px;
  align-items: center;
}





.no-videos {
  text-align: center;
  padding: 60px 40px 60px 40px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
  border: 2px dashed #dee2e6;
  margin: 0;
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.no-telemetry {
  text-align: center;
  padding: 40px 30px 40px 30px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
  border: 2px dashed #dee2e6;
  margin: 0;
  min-height: 250px;
  display: flex;
  align-items: center;
  justify-content: center;
}



.empty-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.empty-title {
  color: #495057;
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}

.empty-tip {
  color: #6c757d;
  font-size: 13px;
  margin: 0;
  line-height: 1.4;
  text-align: center;
  max-width: 300px;
}
.detail-content-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 0;
  overflow: hidden;
}

.detail-content-area:has(.no-videos) {
  gap: 0;
}
.content-area {
  display: flex;
  gap: 20px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.video-section {
  flex: 2;
  background: white;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.screen-section {
  flex: 1;
  background: white;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #f0f0f0;
  flex-shrink: 0;
  background: #fafafa;
}
.section-header h3 {
  margin: 0;
  color: #333;
  font-size: 15px;
  font-weight: 600;
}
.video-info,
.chart-info {
  font-size: 13px;
  color: #666;
  display: flex;
  align-items: center;
}
.video-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  /* padding: 16px; */
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.video-item {
  position: relative;
  border: 2px solid #e8e8e8;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.2s ease;
  background: #f8f9fa;
  min-height: 0;
}
.video-item:hover {
  border-color: #409eff;
}
.video-item.active {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}
.video-info-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
  color: white;
  padding: 4px 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.video-title {
  font-size: 11px;
  font-weight: 500;
}
.screen-preview {
  flex: 1;
  padding: 16px;
  min-height: 0;
  overflow: hidden;
}
.screen-container {
  width: 100%;
  height: 100%;
  border: 2px dashed #d9d9d9;
  border-radius: 4px;
  position: relative;
  overflow: hidden;
  transition: all 0.2s ease;
}
.screen-container.has-data {
  border-color: #52c41a;
  border-style: solid;
}
.screen-player {
  position: relative;
  width: 100%;
  height: 100%;
}
.screen-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}
.screen-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
}
.play-button {
  width: 64px;
  height: 64px;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  cursor: pointer;
  transition: all 0.3s ease;
}
.play-button:hover {
  background: rgba(0, 0, 0, 0.8);
  transform: scale(1.1);
}
.screen-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #999;
}
.chart-section {
  background: white;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  height: 280px;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
}

.chart-section:has(.no-telemetry) {
  height: auto;
  min-height: 280px;
}
.chart-area {
  flex: 1;
  padding: 16px;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding-bottom: 16px;
}

.chart-area:has(.no-telemetry) {
  overflow: visible;
  min-height: 280px;
  padding-bottom: 16px;
}
.chart-area .historical-chart {
  height: 100%;
  min-height: 220px;
}
.playback-section {
  background: white;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  margin-top: 12px;
  flex-shrink: 0;
  overflow: hidden;
}
.playback-controls {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  gap: 20px;
  background: #fafafa;
  border-radius: 8px;
}
.control-left,
.control-right {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 80px;
}
.control-right {
  justify-content: flex-end;
}
.current-time,
.total-time {
  font-family: "Courier New", monospace;
  font-size: 14px;
  color: #333;
  font-weight: 600;
}
.play-btn {
  background: #409eff !important;
  border-color: #409eff !important;
  color: white !important;
}
.progress-container {
  flex: 1;
  position: relative;
}
.progress-slider {
  --el-slider-runway-bg-color: rgba(0, 0, 0, 0.1);
  --el-slider-main-bg-color: #409eff;
  --el-slider-button-size: 18px;
}
.video-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.toolbar-label {
  font-size: 14px;
  color: #333;
  margin-right: 4px;
}
.video-scroll-wrapper {
  max-height: 600px;
  min-height: 180px;
  height: auto;
  overflow-y: auto;
  background: transparent;
  border-radius: 8px;
}

.video-scroll-wrapper:has(.no-videos) {
  max-height: none;
  overflow-y: visible;
  height: auto;
}
.video-grid {
  width: 100%;
  margin: 0 auto;
  min-height: 200px;
  display: grid;
  gap: 16px;
}
.video-card {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  min-height: 180px;
  aspect-ratio: 16/10;
  width: 100%;
}
.video-card-topbar {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  width: calc(100% - 16px);
}
.video-title {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 4px;
  padding: 2px 8px;
  pointer-events: auto;
  max-width: calc(100% - 80px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}
.video-status-text {
  font-weight: bold;
  margin-left: 8px;
  font-size: 15px;
  letter-spacing: 1px;
}
.video-status-text.online {
  color: #21c521;
  text-shadow: 0 0 2px #0a7a0a;
}
.video-status-text.offline {
  color: #ff3b3b;
  text-shadow: 0 0 2px #a10000;
}
.video-card-icons {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  display: flex;
  gap: 8px;
  pointer-events: auto;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 4px;
  padding: 2px 4px;
}
.video-icon {
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  transition: color 0.2s, transform 0.2s;
  opacity: 0.9;
}
.video-icon:hover {
  color: #ffd700;
  opacity: 1;
  transform: scale(1.18);
}
.video-card-body {
  flex: 1 1 0;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  height: 100%;
}
.video-player {
  width: 100% !important;
  height: 100% !important;
}
.video-container,
.video-container video {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
}
@media (max-width: 1200px) {
  .content-area {
    flex-direction: column;
    gap: 16px;
  }
  .video-section,
  .screen-section {
    flex: none;
    height: 300px;
  }
  .video-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}
@media (max-width: 768px) {
  .data-detail {
    padding: 12px;
    gap: 12px;
  }
  .video-grid {
    grid-template-columns: 1fr !important;
  }
  .header-bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

.video-card.selected {
  border: 2px solid #409eff;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

.video-checkbox {
  position: absolute;
  bottom: 8px;
  left: 8px;
  border-radius: 4px;
}

.video-checkbox .el-checkbox {
  --el-checkbox-text-color: white;
}

.enlarged-video-dialog {
  --el-dialog-content-font-size: 16px;
}

.fullscreen-dialog {
  --el-dialog-margin-top: 0;
  --el-dialog-bg-color: #000;
}

.fullscreen-dialog .el-dialog {
  margin: 0;
  border-radius: 0;
  background: #000;
}

.fullscreen-dialog .el-dialog__header {
  padding: 12px 20px;
  background: rgba(0, 0, 0, 0.8);
  border-bottom: 1px solid #333;
  position: relative;
}

.fullscreen-dialog .el-dialog__headerbtn {
  position: absolute;
  top: 12px;
  right: 20px;
  z-index: 10;
}

.fullscreen-dialog .el-dialog__headerbtn .el-dialog__close {
  color: #fff;
  font-size: 20px;
  transition: all 0.3s ease;
}

.fullscreen-dialog .el-dialog__headerbtn .el-dialog__close:hover {
  color: #f56c6c;
  transform: scale(1.1);
}

.fullscreen-dialog .el-dialog__body {
  padding: 0;
  height: calc(100vh - 60px);
  background: #000;
  overflow: hidden;
}

.fullscreen-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.dialog-title {
  color: white;
  font-size: 18px;
  font-weight: 600;
}



.enlarged-video-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #000;
  overflow: hidden;
}

.enlarged-video-grid {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.enlarged-video-grid.single-video {
  padding: 0;
  align-items: center;
  justify-content: center;
}

.enlarged-video-grid.multi-video {
  padding: 20px;
  overflow: auto;
}

.enlarged-video-item {
  background: #111;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid #333;
}

.enlarged-video-item.single-video {
  width: 100%;
  height: 100%;
  border-radius: 0;
  border: none;
  background: #000;
}

.enlarged-video-item.single-video .enlarged-video-header {
  position: absolute;
  top: 20px;
  left: 20px;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 4px;
  z-index: 10;
  border: none;
}

.enlarged-video-header {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 8px 12px;
  background: #222;
  border-bottom: 1px solid #333;
  font-weight: 600;
  color: white;
}

.enlarged-video-header span {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
}

.enlarged-video-item .video-player {
  flex: 1;
  height: 100%;
}

.enlarged-video-item.single-video .video-player {
  position: relative;
}

.enlarged-playback-controls {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  gap: 20px;
  background: #fff;
  border-top: 1px solid #e8e8e8;
  flex-shrink: 0;
}

.enlarged-control-left,
.enlarged-control-right {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 160px;
  color: #333;
}

.enlarged-control-right {
  justify-content: flex-end;
}

.enlarged-progress-container {
  flex: 1;
  position: relative;
}

.enlarged-playback-controls .el-button {
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
}

.enlarged-playback-controls .el-button:hover {
  background: #f5f7fa;
  border-color: #c0c4cc;
}

.enlarged-playback-controls .current-time,
.enlarged-playback-controls .total-time {
  color: #333;
  font-family: monospace;
  font-weight: 500;
}

.enlarged-playback-controls .progress-slider {
  --el-slider-runway-bg-color: #e4e7ed;
  --el-slider-main-bg-color: #409eff;
  --el-slider-button-size: 16px;
}
</style>
